package com.shj.em.biz.prod.service;

import com.shj.em.biz.sell.entity.Order;
import com.shj.em.biz.sell.mapper.OrderMapper;
import com.shj.em.biz.prod.dto.OrderEffortDTO;
import com.shj.em.biz.prod.entity.Effort;
import com.shj.em.biz.prod.mapper.EffortMapper;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;

import com.baomidou.mybatisplus.plugins.Page;

import java.math.BigDecimal;
import java.util.*;

import com.shj.em.biz.hr.entity.Emp;
import com.shj.em.biz.sys.entity.EmpRank;
import com.shj.em.biz.sys.entity.RankAmount;
import com.shj.em.biz.sys.mapper.EmpRankMapper;
import com.shj.em.biz.sys.mapper.RankAmountMapper;
import com.shj.em.biz.sys.service.CdService;
import com.shj.em.biz.sys.service.DeptEmpService;
import com.shj.em.biz.hr.service.EmpService;
import com.shj.em.util.DateUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;


/**
 * 员工工作时间表 服务实现类
 *
 * @author Shen Huang Jian
 * @since 2018-07-16
 */
@Service
@Slf4j
@Transactional
public class EffortServiceImpl extends ServiceImpl<EffortMapper, Effort> implements EffortService {

    @Autowired
    EffortMapper effortMapper;

    @Autowired
    DeptEmpService deptEmpService;

    @Autowired
    OrderMapper orderMapper;

    @Autowired
    EmpRankMapper empRankMaper;

    @Autowired
    RankAmountMapper rankAmountMapper;

    @Autowired
    EmpService empService;

    @Autowired
    CdService cdService;

    public Page<Effort> queryEffortPage(Map<String, Object> params){
        int offset = (Integer)params.get("offset");
        int pageSize = (Integer)params.get("limit");
        int pageNo = offset / pageSize + 1;
        Page<Effort> page = new Page(pageNo, pageSize);
        List<Effort> list = effortMapper.queryEffortPage(page, params);
        return page.setRecords(list);
    }

    public List<Effort> findEffortsByDeptOrderAndDt(Long deptId, Long orderId, Date workDt){
        return effortMapper.findEffortsByDeptOrderAndDt(deptId, orderId, DateUtils.format(workDt, DateUtils.DATE_PATTERN));
    }

    public Map<Long, BigDecimal> getOrderTotalEffort(int year){
        String yearBegin = year + "-01-01";
        String yearEnd = year + "-12-31";
        List<Effort> efforts =  effortMapper.getOrderTotalEffort(yearBegin, yearEnd);
        Map<Long, BigDecimal> map = new HashMap<>();
        for(Effort effort : efforts){
            map.put(effort.getOrderId(), effort.getWorkHour());
        }
        return map;
    }

    public Map<Long, List<BigDecimal>> getEmpTotalEffortPerMonth(int year){
        String yearBegin = year + "-01-01";
        String yearEnd = year + "-12-31";
        List<Effort> efforts = effortMapper.getEmpTotalEffortPerMonth(yearBegin, yearEnd);
        Map<Long, List<BigDecimal>> empTotalEffortPerMonth = new HashMap<>();
        for(Effort effort : efforts){
            if(!empTotalEffortPerMonth.containsKey(effort.getEmpId())){
                empTotalEffortPerMonth.put(effort.getEmpId(), prepareDefaultTotal());
            }
            empTotalEffortPerMonth.get(effort.getEmpId()).add(effort.getMonth()-1, effort.getWorkHour());
        }
        return empTotalEffortPerMonth;
    }

    public List<Effort> getEmpEffortPerOrder(int year){
        String yearBegin = year + "-01-01";
        String yearEnd = year + "-12-31";
        return effortMapper.getEmpEffortPerOrder(yearBegin, yearEnd);
    }

    public List<Effort> getEmpEffortInYear(int year){
        String yearBegin = year + "-01-01";
        String yearEnd = year + "-12-31";
        return effortMapper.getEmpEffortInYear(yearBegin, yearEnd);
    }

    private List<BigDecimal> prepareDefaultTotal(){
        List<BigDecimal> defaultTwelve = new ArrayList<>();
        for(int i = 0 ; i < 12; i++){
            defaultTwelve.add(new BigDecimal(0.00));
        }
        return defaultTwelve;
    }

    public RankAmount getEmpRankAmount(int year, int month, Long empId){
        String begin = year + "-" + month + "-" + "01";

        //这里有一个问题，员工可能在这个月的中间就升级了，用此处得到的等级计算时，
        //和在报表里得出的值会有偏差，但是这个功能仅为显示原始值，影响不大
        List<EmpRank> empRanks = empRankMaper.findEmpRanks(empId, begin);

        RankAmount rankAmount = new RankAmount();

        if(empRanks != null && empRanks.size() > 0){
            rankAmount.setRankDescr(cdService.getDescrByTypeAndCd(CdService.CD_TYPE_RANK, empRanks.get(0).getRank()));

            // rank 对应的金额
            List<RankAmount> rankAmounts = rankAmountMapper.findRankAmountsByRank(empRanks.get(0).getRank(), begin);
            if(rankAmounts != null && rankAmounts.size() > 0){
                rankAmount.setMax(rankAmounts.get(0).getMax());
                rankAmount.setMin(rankAmounts.get(0).getMin());
            }
        }

        return rankAmount;
    }

    public List<OrderEffortDTO> getEmpWorkOrderInfo(int year, int month, long empId){
        String begin = year + "-" + month + "-" + "01";
        String end;
        if(month == 12){
            end = (year+1) + "-01-01";
        }else{
            end = year + "-" + (month + 1) + "-" + "01";
        }

        List<OrderEffortDTO> list = new ArrayList<>();
        List<Effort> empWorkHours = effortMapper.getEffortPerOrderOfEmp(begin, end, empId);

        List<Order> orders = orderMapper.getEmpWorkOrders(begin, end, empId);
        List<Effort> orderTotalHour = effortMapper.getTotalWorkHourOfWorkOrders(begin, end, empId);

        for(Order order : orders){
            OrderEffortDTO orderEffortDTO = new OrderEffortDTO();
            orderEffortDTO.setOrderId(order.getId());
            orderEffortDTO.setOrderNo(order.getOrderNo());
            orderEffortDTO.setOrderAmount(order.getTotalAmount());
            orderEffortDTO.setOrderStatus("F".equalsIgnoreCase(order.getShipmentStatus()) ? "完成生产" : "未完成生产");

            // 设置订单的总的工作时间
            for(Effort tmp : orderTotalHour){
                if(tmp.getOrderId().equals(order.getId())){
                    orderEffortDTO.setTotalWorkHour(tmp.getWorkHour());
                    break;
                }
            }

            //设置此员工在此订单上花费的时间
            for(Effort tmp : empWorkHours){
                if(tmp.getOrderId().equals(order.getId())){
                    orderEffortDTO.setEmpWorkHour(tmp.getWorkHour());
                    break;
                }
            }

            list.add(orderEffortDTO);
        }

        return list;
    }

    public List<Emp> getEmpsByDeptId(int year, int month, long deptId){
        String begin = year + "-" + month + "-" + "01";
        String end;
        if(month == 12){
            end = (year+1) + "-01-01";
        }else{
            end = year + "-" + (month + 1) + "-" + "01";
        }
        return effortMapper.getEmpsByDeptId(begin, end, deptId);
    }

}
